#include <winsock2.h>
#include "Community/gameroom.h"
#include "../../common/protocol.h"
#include "Community/ChannelManager.h"

GameRoom::GameRoom()
{
}

GameRoom::~GameRoom()
{
}

DWORD GameRoom::create( Character *character )
{
	DWORD enterResult = enter( character );
	if ( enterResult != error::No_Error ) return ( enterResult );

	character->setReady( true );
	character->setChannelMaster( true );

	SYNC_GET_PACKET( packet );
	makeEnterChannelAck( packet );
	character->send( packet );

	SYNC_GET_PACKET( addUserPacket );
	makeAddUserAck( addUserPacket, character );
	character->send( addUserPacket );

	return ( error::No_Error );
}

void GameRoom::initializeValue( int channelNumber )
{
	initialize();

	m_number = channelNumber;
	ZeroMemory( m_name, MAX_CHANNEL_NAME + 1 );
	m_maxJoinSize = DEFAULT_CHANNEL_MAX_JOIN_SIZE;
	m_attribute = 0;
	m_password = NULL;
}

void GameRoom::readyUser( Character *character, bool ready )
{
	if ( ready == true  && character->isReady() == true ) return;
	if ( ready == false && character->isReady() == false ) return;

	character->setReady( ready );

	SYNC_GET_PACKET( readyPacket );

	readyPacket->ID( protocol::community::ReadyAck );

	*readyPacket << ( const char * )character->getUserID() << ready;

	broadcast( readyPacket );
}

bool GameRoom::makeEnterChannelAck( netlib::packet::Packet *packet )
{
	packet->ID( protocol::community::EnterChannelAck );
	*packet << m_number << m_name << m_maxJoinSize << m_attribute;

	return ( true );
}


bool GameRoom::makeAddChannelAck( netlib::packet::Packet *packet )
{
	packet->ID( protocol::community::AddChannelAck );
	*packet << m_number << m_name;

	return ( true );
}

bool GameRoom::makeRemoveChannelAck( netlib::packet::Packet *packet )
{
	packet->ID( protocol::community::RemoveChannelAck );
	*packet << m_number;

	return ( true );
}

bool GameRoom::changeMaster( Character *newCharacter )
{
	bool changeOk = false;
	char userID[ CHARACTER_ID_LENGTH + 1 ];
	{
		SYNC( &m_sectionUserList );

		dequeUserList::const_iterator iter_end( m_userList.end() );
		for ( dequeUserList::const_iterator iter = m_userList.begin() ; iter != iter_end; ++iter )
		{
			Character *character = ( *iter );
			if ( character && ( ( newCharacter == NULL ) || ( newCharacter == character ) ) )
			{
				character->setReady( true );
				character->setChannelMaster( true );
				strncpy_s( userID, character->getUserID() , CHARACTER_ID_LENGTH );
				changeOk = true;
			}
		}
	}
	sendChangeMaster( userID );

	return  ( changeOk );
}

bool GameRoom::sendChangeMaster( char *userID )
{
	SYNC_GET_PACKET( changeMasterPacket );

	changeMasterPacket->ID( protocol::community::ChangeMasterAck );

	*changeMasterPacket  << userID;

	broadcast( changeMasterPacket );

	return ( true );
}

bool GameRoom::kickOut( Character *character, char *outUser )
{
	if ( !character->isChannelMaster() ) return ( false );

	Character *outCharacter = find( outUser );
	{
		SYNC_GET_PACKET( kickOutPacket );

		kickOutPacket->ID( protocol::community::KickOutAck );

		*kickOutPacket  << outUser;

		broadcast( kickOutPacket );
	}
	return ( true );
}

bool GameRoom::startGame( Character *character )
{
	if ( !character->isChannelMaster() ) return ( false );

	if ( !isAllUserReadyGame() ) return ( false );
	{
		SYNC_GET_PACKET( startGamePacket );

		startGamePacket->ID( protocol::game::StartGameAck );

		broadcast( startGamePacket );
	}

	return ( true );
}

bool GameRoom::startedGame( Character *character )
{
	character->setStartedGame( true );
	if ( !isAllUserStartedGame() ) return ( false );
	{
		SYNC_GET_PACKET( startedGamePacket );

		startedGamePacket->ID( protocol::game::StartedGameAck );

		broadcast( startedGamePacket );
	}

	return ( true );
}


bool GameRoom::isAllUserStartedGame()
{
	{
		SYNC( &m_sectionUserList );

		dequeUserList::const_iterator iter_end( m_userList.end() );
		for ( dequeUserList::const_iterator iter = m_userList.begin() ; iter != iter_end; ++iter )
		{
			Character *character = ( *iter );
			if ( character->isStartedGame() == false ) return ( false );
		}
	}
	return ( true );
}

bool GameRoom::isAllUserReadyGame()
{
	{
		SYNC( &m_sectionUserList );

		dequeUserList::const_iterator iter_end( m_userList.end() );
		for ( dequeUserList::const_iterator iter = m_userList.begin() ; iter != iter_end; ++iter )
		{
			Character *character = ( *iter );
			if ( character->isReady() == false ) return ( false );
		}
	}
	return ( true );
}
